package com.ideaaedi.commonds.sort;


import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors;

/**
 * 排序实现器
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 1.0.0
 */
public class DefaultSortSupporter<T extends Comparable<T>> implements SortSupporter<T> {
    
    @Override
    @SuppressWarnings("AlibabaUndefineMagicConstant")
    public List<T>  autoSort(Collection<T> nonNullList, boolean asc) {
        int size = nonNullList.size();
        if (size < 10_000 || size > 1000_000) {
            return collectionsSort(nonNullList, asc);
        }
        return forkJoinMergeSort(nonNullList, asc);
    }
    
    @Override
    @SuppressWarnings({"unchecked"})
    public  List<T>  forkJoinMergeSort(Collection<T> nonNullList, boolean asc) {
        //noinspection OptionalGetWithoutIsPresent
        T t = nonNullList.stream().findAny().get();
        T[] toBeenSortedData = nonNullList.toArray((T[])Array.newInstance(t.getClass(), nonNullList.size()));
        MergeSortCompleter<T> task = new MergeSortCompleter<>(null, toBeenSortedData, 0, toBeenSortedData.length - 1, asc);
        // invoke内部调用了join方法
        ForkJoinPool.commonPool().invoke(task);
        return new ArrayList<>(Arrays.asList(toBeenSortedData));
    }
    
    @Override
    public List<T> collectionsSort(Collection<T> nonNullList, boolean asc) {
        List<T> list = nonNullList.stream().sorted().collect(Collectors.toList());
        if (!asc) {
            Collections.reverse(list);
        }
        return list;
    }
}
